/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tal.drivechain.gui;

import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.util.HashMap;
import tal.drivechain.parsing.ParsingAid;
import tal.drivechain.parsing.Tokenizer;

/**
 *
 * @author eisental
 */
public class LayoutParser {
    public static Object parseLayout(String prop, HashMap<String,String> attributes) throws IllegalArgumentException {
        //returns GridBagConstraints x,y,width,height,ipad-width,ipad-height,pad-bottom,pad-top,pad-left,pad-right,anchor,weightx,weighty,fill
        //syntax prop-name:prop-val,...,prop-name:prop-val
        dcLayout ret = dcLayout.createNewLayout();
        prop = prop.trim();
        if (prop.equals("default") || prop.equals("")) return ret;
        Insets padding = new Insets(0,0,0,0);
        Tokenizer tokenizer = new Tokenizer(prop, ',');
        while(tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            int colIndex = token.indexOf(':');
            if (colIndex==-1 || colIndex>=token.length()-1)
                throw new IllegalArgumentException("A layout constraints property syntax is prop-name:prop-value (" + token + ").");
            else {
                String propName = token.substring(0, colIndex).trim();
                String propValue = token.substring(colIndex+1).trim();
                addConstraintProperty(propName, propValue, ret, padding);
            }
        }
        ret.insets = padding;
        return ret;
    }

    private static void addConstraintProperty(String propName, String propValue, dcLayout c, Insets padding) {
        propName = propName.trim();
        if (propName.equals("x")) {
            c.gridx = ParsingAid.parseInteger(propValue);
        } else if (propName.equals("y")) {
            c.gridy = ParsingAid.parseInteger(propValue);
        } else if (propName.equals("width")) {
            if (propValue.equals("remainder"))
                c.gridwidth = GridBagConstraints.REMAINDER;
            else if (propValue.equals("relative"))
                c.gridwidth = GridBagConstraints.RELATIVE;
            else
                c.gridwidth = ParsingAid.parseInteger(propValue);
        } else if (propName.equals("height")) {
            if (propValue.equals("remainder"))
                c.gridheight = GridBagConstraints.REMAINDER;
            else if (propValue.equals("relative"))
                c.gridwidth = GridBagConstraints.RELATIVE;
            else
                c.gridheight = ParsingAid.parseInteger(propValue);
        } else if (propName.equals("ipad-width")) {
            c.ipadx = ParsingAid.parseInteger(propValue);
        } else if (propName.equals("ipad-height")) {
            c.ipady = ParsingAid.parseInteger(propValue);
        } else if (propName.equals("anchor")) {
            c.anchor = (Integer)parseAnchor(propValue);
        } else if (propName.equals("weightx")) {
            c.weightx = ParsingAid.parseDouble(propValue);
        } else if (propName.equals("weighty")) {
            c.weighty = ParsingAid.parseDouble(propValue);
        } else if (propName.equals("fill")) {
            c.fill = (Integer)parseFill(propValue);
        } else if (propName.equals("pad-top")) {
            padding.top = ParsingAid.parseInteger(propValue);
        } else if (propName.equals("pad-bottom")) {
            padding.bottom = ParsingAid.parseInteger(propValue);
        } else if (propName.equals("pad-left")) {
            padding.left = ParsingAid.parseInteger(propValue);
        } else if (propName.equals("pad-right")) {
            padding.right = ParsingAid.parseInteger(propValue);
        } else {
            throw new IllegalArgumentException("Unknown layout constraints property " + propName);
        }
    }

    private static Object parseAnchor(Object value) {
        HashMap<String, Integer> a = new HashMap<String, Integer>();
        a.put("first.line.start", GridBagConstraints.FIRST_LINE_START);
        a.put("line.start", GridBagConstraints.LINE_START);
        a.put("last.line.start", GridBagConstraints.LAST_LINE_START);
        a.put("page.start", GridBagConstraints.PAGE_START);
        a.put("center", GridBagConstraints.CENTER);
        a.put("page.end", GridBagConstraints.PAGE_END);
        a.put("first.line.end", GridBagConstraints.FIRST_LINE_END);
        a.put("line.end", GridBagConstraints.LINE_END);
        a.put("last.line.end", GridBagConstraints.LAST_LINE_END);
        a.put("northwest", GridBagConstraints.NORTHWEST);
        a.put("north", GridBagConstraints.NORTH);
        a.put("northeast", GridBagConstraints.NORTHEAST);
        a.put("west", GridBagConstraints.WEST);
        a.put("east", GridBagConstraints.EAST);
        a.put("southwest", GridBagConstraints.SOUTHWEST);
        a.put("south", GridBagConstraints.SOUTH);
        a.put("southeast", GridBagConstraints.SOUTHEAST);

        if (value instanceof String) {
            Integer ret = a.get((String)value);
            if (ret==null)
                throw new IllegalArgumentException("Unknown anchor layout constraints property value: " + value);
            else return ret;
        } else if (value instanceof Integer) {
            for (String s : a.keySet())
                if (a.get(s).equals(value))
                    return s;
            throw new IllegalArgumentException("Unknown anchor constant code: " + value);

        } else throw new IllegalArgumentException("Illegal class for value parameter: " + value.getClass().getName());
    }

    private static Object parseFill(Object value) {
        HashMap<String, Integer> f = new HashMap<String,Integer>();
        f.put("none", GridBagConstraints.NONE);
        f.put("horizontal", GridBagConstraints.HORIZONTAL);
        f.put("vertical", GridBagConstraints.VERTICAL);
        f.put("both", GridBagConstraints.BOTH);

        if (value instanceof String) {
            Integer i = f.get((String)value);
            if (i==null)
                throw new IllegalArgumentException("Unknown fill layout constraints property value: " + value);
            else return i;
        } else if (value instanceof Integer) {
            for (String s : f.keySet())
                if (f.get(s).equals(value))
                    return s;
            throw new IllegalArgumentException("Unknown fill layout code: " + value);
        } else throw new IllegalArgumentException("Illegal class for value parameter: " + value.getClass().getName());
    }

    public static String layoutToString(Object prop, HashMap attributes) {
        dcLayout ref = dcLayout.createNewLayout();
        dcLayout layout = (dcLayout)prop;
        if (layout==null) layout = dcLayout.createNewLayout();
        String ret="";

        if (layout.anchor!=ref.anchor)
            ret = "anchor: " + (String)parseAnchor(layout.anchor) + ", ";
        if (layout.fill!=ref.fill)
            ret += "fill: " + (String)parseFill(layout.fill) + ", ";
        if (layout.gridheight!=ref.gridheight) {
            String gridheight;
            if (layout.gridheight==GridBagConstraints.REMAINDER)
                gridheight = "remainder";
            else if (layout.gridheight==GridBagConstraints.RELATIVE)
                gridheight = "relative";
            else gridheight = ""+layout.gridheight;
            ret += "height: " + gridheight + ", ";
        } if (layout.gridwidth!=ref.gridwidth) {
            String gridwidth;
            if (layout.gridwidth==GridBagConstraints.REMAINDER)
                gridwidth = "remainder";
            else if (layout.gridwidth==GridBagConstraints.RELATIVE)
                gridwidth = "relative";
            else gridwidth = ""+layout.gridwidth;
            ret += "width: " + gridwidth + ", ";
        } if (layout.gridx!=ref.gridx)
            ret += "x: " + layout.gridx + ", ";
        if (layout.gridy!=ref.gridy)
            ret += "y: " + layout.gridy + ", ";
        if (layout.insets.bottom!=ref.insets.bottom)
            ret += "pad-bottom: " + layout.insets.bottom + ", ";
        if (layout.insets.left!=ref.insets.left)
            ret += "pad-left: " + layout.insets.left + ", ";
        if (layout.insets.right!=ref.insets.right)
            ret += "pad-right: " + layout.insets.right + ", ";
        if (layout.insets.top!=ref.insets.top)
            ret += "pad-top: " + layout.insets.top + ", ";
        if (layout.ipadx!=ref.ipadx)
            ret += "ipad-width: " + layout.ipadx + ", ";
        if (layout.ipady!=ref.ipady)
            ret += "ipad-height: " + layout.ipadx + ", ";
        if (layout.weightx!=ref.weightx)
            ret += "weightx: " + layout.weightx + ", ";
        if (layout.weighty!=ref.weighty)
            ret += "weighty: " + layout.weighty + ", ";

        if (ret.length()>1)
            return ret.substring(0, ret.length()-2);
        else return ret;
    }

}
